package nl.rainbowsheep.reisorg.rest.service.controller;

import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import nl.rainbowsheep.reisorg.rest.service.controller.exception.EntityNotFoundException;
import static nl.rainbowsheep.reisorg.rest.service.controller.helper.RandomPasswordGenerator.getRandomString;
import nl.rainbowsheep.reisorg.rest.service.model.BurritoUser;
import nl.rainbowsheep.reisorg.rest.service.model.Customer;
import nl.rainbowsheep.reisorg.rest.service.service.CustomerService;
import nl.rainbowsheep.reisorg.rest.service.service.MailingService;
import nl.rainbowsheep.reisorg.rest.service.service.TravelGroupService;
import nl.rainbowsheep.reisorg.rest.service.service.UserService;
import nl.rainbowsheep.reisorg.rest.service.viewmodel.CustomerViewmodel;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.security.acls.model.NotFoundException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * Controller for customers
 */
@RestController
@RequestMapping("/customer")
public class CustomerController {

    /**
     * use slf4j logger during debugging
     */
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(CustomerController.class);

    @Autowired
    CustomerService customerService;

    @Autowired
    MailingService mailingService;

    @Autowired
    UserService burritoUserService;

    @Autowired
    UserService userService;

    @Autowired
    TravelGroupService travelgroupService;

    @RequestMapping(value = "/pages", method = RequestMethod.GET)
    public Page<Customer> getCustomers(@RequestParam(value = "pageIndex", required = false, defaultValue = "0") Integer pageIndex, @RequestParam(value = "size", required = false, defaultValue = "20") Integer size) {
        Pageable pageable = new PageRequest(pageIndex, size, new Sort("id"));
        Page<Customer> pageResult = customerService.findAll(pageable);
        return pageResult;
    }

    /**
     * save methods in services and repo's handle inserts and updates
     *
     * @param customerViewmodel
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public CustomerViewmodel saveCustomerViewmodel(@RequestBody CustomerViewmodel customerViewmodel) throws Exception {
        if (customerViewmodel.getCustomer().getRegistrationDate() == null) {
            customerViewmodel.getCustomer().setRegistrationDate(new Date());
            customerViewmodel.getCustomer().setIsActive(true);
        }
        try {
            return customerService.save(customerViewmodel);
        } catch (Exception ex) {
            throw new Exception(ex.toString());
        }
    }

    /**
     * Get details of a customer by id of customer
     *
     * @param id id of customer
     * @return the customer object
     */
    @RequestMapping(value = "/details/id/{id}", method = RequestMethod.GET)
    public Customer getCustomerDetails(@PathVariable Long id) throws NotFoundException {
        try {
            Customer customer = customerService.getCustomerById(id);
            return customer;
        } catch (Exception ex) {
            Logger.getLogger(CustomerController.class.getName()).log(Level.SEVERE, null, ex);
            throw new NotFoundException(id.toString());
        }
    }

    /**
     * get details of a customer by username of BurritoUser
     *
     * @param username username of a user
     * @return customer belonging to the username
     * @throws NotFoundException
     */
    @RequestMapping(value = "/details/username", method = RequestMethod.GET)
    public CustomerViewmodel getCustomerViewmodelDetailsByUsername(@RequestParam(value = "username") String username) throws EntityNotFoundException {

        CustomerViewmodel customerViewmodel = customerService.getCustomerViewmodelByUsername(username);
        if (customerViewmodel == null) {
            throw new EntityNotFoundException(username);
        }
        return customerViewmodel;
    }

    /**
     * Reset the password if the given username an email adres belong to
     * eachother
     *
     * @param username
     * @param customerViewmodel
     * @return boolean if password reset has been done succesffully
     */
    @RequestMapping(value = "/resetpassword/{username}", method = RequestMethod.POST)
    public boolean resetPassword(@PathVariable String username, @RequestBody CustomerViewmodel customerViewmodel) {
        boolean result = false;
        int length = 8;
        Customer customer = customerService.getCustomerByUsername(username);
        if (customer != null) {
            if (customerViewmodel.getCustomer().getEmail().equals(customer.getEmail())) {
                String password = getRandomString(length);

                long burritoUserId = customer.getBurritoUserId();
                BurritoUser newpasswordBurritoUser = userService.findByBurritoUserId(burritoUserId);

                newpasswordBurritoUser.setPassword(password);
//                customer.getBurritoUser().setPassword(password);
//                BurritoUser savedUser = burritoUserService.save(customer.getBurritoUser());
                BurritoUser savedUser = burritoUserService.save(newpasswordBurritoUser);
                if (savedUser != null) {
                    this.sendMail(username, "Uw nieuwe wachtwoord is: " + password);
                    result = true;
                }

            }
        }
        return result;
    }

    /**
     * JUST AN EXAMPLE HOW TO SEND A MAIL. NEVER USER THIS WITH A GET
     * REQUEST!!!!!!
     *
     * @param username
     * @param messageString
     * @return
     */
    @RequestMapping(value = "/sendMail", method = RequestMethod.GET)
    @ResponseBody
    public HttpStatus sendMail(@RequestParam(value = "username", required = true) String username, @RequestParam(value = "message", required = true) String messageString) {
        Customer cust = customerService.getCustomerByUsername(username);
        if (cust != null) {
            mailingService.sendMail(cust.getEmail(), "Subject - Mail from spring", messageString);
        }
        return HttpStatus.OK;
    }

    @RequestMapping(value = "/find", method = RequestMethod.POST)
    @ResponseBody
    public List<Customer> findCustomer(@RequestBody Customer customer) {
        List<Customer> customers = customerService.findCustomers(customer);
        return customers;
    }

}
